package cn.sitcat.springbootshiro.configs;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author hiseico
 * @date 2019/4/13 17:58
 * @desc Shiro的配置类
 */
//声明该类为配置类
@Configuration
public class ShiroConfig {
    /**
     * 创建ShiroFilterFactoyBean
     * @param securityManager
     * @return
     */
    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("webSecurityManager") DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //添加shiro内置过滤器
        /**
         * shiro内置过滤器，可以实现权限的拦截器
         * 常用的过滤器：
         *  anon:无需认证（登录）可以访问
         *  authc:必须认证才可以访问
         *  user:如果使用remeberMe的功能可以直接访问
         *  perms:该资源必须得到资源权限才可以访问
         *  role:该资源必须得到角色权限才可以访问
         */
        Map<String, String> filterMap = new LinkedHashMap<>();
       /* filterMap.put("/add","authc");
        filterMap.put("/update","authc");
        */
        //使用统配的过滤器拦截多个url
        filterMap.put("/login", "anon");
        filterMap.put("/test", "anon");

        //授权过滤器
        //注意：当授权拦截后，shiro会自动跳转到未授权页面
        filterMap.put("/add", "perms[user:add]");
        filterMap.put("/update", "perms[user:update]");

        //认证过滤器
        filterMap.put("/*", "authc");

        //设置未授权提示页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noAuth");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);

        //修改拦截后跳转的url
        shiroFilterFactoryBean.setLoginUrl("/login");
        return shiroFilterFactoryBean;
    }


    /**
     * 创建DefaultWebSecurityManager
     * @Qualifier 从ioc容器中找到这个对象
     *
     * @param userRealm
     * @return
     */
    @Bean(name = "webSecurityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("realm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    /**
     * 创建Realm
     * 使用@Bean将该方法的返回值放到IOC容器中
     * @return
     */
    @Bean(name = "realm")
    public UserRealm getShiroRealm() {
        return new UserRealm();
    }

    /**
     * 配置shiroDialect,用于thymeleaf和shiro标签配置使用
     * @return
     */
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}
